/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.comac.ins.common.core.exception.ServiceException;
import com.comac.ins.common.core.utils.StreamUtils;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.common.core.utils.file.FileUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.common.oss.core.OssClient;
import com.comac.ins.common.oss.entity.UploadResult;
import com.comac.ins.common.oss.enumd.AccessPolicyType;
import com.comac.ins.common.oss.factory.OssFactory;
import com.comac.ins.common.satoken.utils.LoginHelper;
import com.comac.ins.isfd.constant.enums.IsfdImportMethodEnum;
import com.comac.ins.isfd.constant.enums.IsfdMongoQueryLogicalOperatorEnum;
import com.comac.ins.isfd.constant.enums.IsfdMongoQueryOperatorEnum;
import com.comac.ins.isfd.domain.IsfdDatabaseModelConfig;
import com.comac.ins.isfd.domain.IsfdDatabaseMongoQuery;
import com.comac.ins.isfd.domain.bo.IsfdDatabaseDataImportRecordBo;
import com.comac.ins.isfd.domain.bo.IsfdFluidModelBo;
import com.comac.ins.isfd.domain.vo.*;
import com.comac.ins.isfd.mapper.IsfdBusinessDatabaseRefMapper;
import com.comac.ins.isfd.mapper.IsfdDatabaseModelConfigMapper;
import com.comac.ins.isfd.service.IIsfdDatabaseDataImportRecordService;
import com.comac.ins.isfd.service.IIsfdDatabaseMongoService;
import com.comac.ins.isfd.service.IsfdFluidModelService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.bson.Document;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * 流体库service层接口实现层
 *
 * 123
 * @date 2024-7-1
 */
@RequiredArgsConstructor
@Service
public class IsfdFluidModelServiceImpl implements IsfdFluidModelService {

    @Autowired
    private final IsfdDatabaseModelConfigMapper isfdDatabaseModelConfigMapper;
    @Autowired
    private final IsfdDatabaseDataManagementServiceImpl isfdDatabaseDataManagementService;
    @Autowired
    private IIsfdDatabaseMongoService mongoService;
    @Autowired
    private IIsfdDatabaseDataImportRecordService importRecordService;
    @Autowired
    private IsfdBusinessDatabaseRefMapper isfdBusinessDatabaseRefMapper;

    @Override
    public TableDataInfo<IsfdFluidModelVo> queryPageList(IsfdFluidModelBo bo, PageQuery pageQuery) {
        // 构建查询条件
        List<IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition> conditions = new ArrayList<>();
        IsfdDatabaseMongoQuery queryCondition = new IsfdDatabaseMongoQuery();
        IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition itemCondition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
        if(com.anwen.mongo.toolkit.StringUtils.isNotBlank(bo.getName())){
            itemCondition.setFieldName("name");
            itemCondition.setValue(bo.getName());
            itemCondition.setLogicalOperator(IsfdMongoQueryLogicalOperatorEnum.AND.getValue());
            itemCondition.setOperator(IsfdMongoQueryOperatorEnum.LIKE.getValue());
            conditions.add(itemCondition);
        }
        conditions.add(itemCondition);
        queryCondition.setConditions(conditions);
        IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectModelByModelName("流体通用模型");
        if(Objects.nonNull(pageQuery.getPageNum())) {
            pageQuery.setPageNum(pageQuery.getPageNum());
        }else{
            pageQuery.setPageNum(1);
        }
        if(Objects.nonNull(pageQuery.getPageSize())) {
            pageQuery.setPageSize(pageQuery.getPageSize());
        }else{
            pageQuery.setPageSize(10);
        }
        queryCondition.setPageQuery(pageQuery);
        Long tableDataCount = mongoService.count(modelConfig.getTableName());
        List<Document> documents = isfdDatabaseDataManagementService.queryDataByModelHasRecord(modelConfig.getId(),queryCondition);
        // 循环遍历查询结果
        List<IsfdFluidModelVo> resultList = new ArrayList<>();
        for (Document document : documents) {
            IsfdFluidModelVo IsfdFluidModelVo = new IsfdFluidModelVo();
            IsfdFluidModelVo.setName(document.getString("name"));
            IsfdFluidModelVo.setDesity(document.getString("desity"));
            IsfdFluidModelVo.setGasConstant(document.getString("gas_constant"));
            IsfdFluidModelVo.setInternalEnergy(document.getString("internal_energy"));
            IsfdFluidModelVo.setLatentHeat(document.getString("latent_heat"));
            IsfdFluidModelVo.setMassDiffusivity(document.getString("mass_diffusivity"));
            IsfdFluidModelVo.setPressure(document.getString("pressure"));
            IsfdFluidModelVo.setSaturationPressure(document.getString("saturation_pressure"));
            IsfdFluidModelVo.setSaturationTemperature(document.getString("saturation_temperature"));
            IsfdFluidModelVo.setSpecificHeatCapacity(document.getString("specific_heat_capacity"));
            IsfdFluidModelVo.setSpecificHeatRatio(document.getString("specific_heat_ratio"));
            IsfdFluidModelVo.setSurfaceTension(document.getString("specific_heat_ratio"));
            IsfdFluidModelVo.setTemperature(document.getString("temperature"));
            IsfdFluidModelVo.setThermalConductivity(document.getString("thermal_conductivity"));
            IsfdFluidModelVo.setViscosity(document.getString("viscosity"));
            IsfdFluidModelVo.setId(document.getString("_id"));
            IsfdFluidModelVo.setModelId(document.getString("_id"));
            IsfdFluidModelVo.setFileName(document.getString("file_name"));
            IsfdFluidModelVo.setOriginalName(document.getString("original_name"));
            IsfdFluidModelVo.setFileSuffix(document.getString("file_suffix"));
            IsfdFluidModelVo.setService(document.getString("service"));
            IsfdFluidModelVo.setUrl(document.getString("url"));
            resultList.add(IsfdFluidModelVo);
        }
        Page<IsfdFluidModelVo> result = new Page<>();
        List<IsfdFluidModelVo> filterResult = StreamUtils.toList(resultList, this::matchingUrl);
        result.setRecords(filterResult);
        result.setCurrent(pageQuery.getPageNum());
        result.setSize(pageQuery.getPageSize());
        result.setTotal(tableDataCount);
        return TableDataInfo.build(result);
    }

    @Override
    public Boolean deleteWithValidByIds(String id, Boolean isValid) {
        try{
            IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectModelByModelName("流体通用模型");
            Document document = mongoService.findById(modelConfig.getTableName(), id);
            // 删除mongo数据
            mongoService.deleteByIds(modelConfig.getTableName(), Collections.singletonList(id));
            // 删除导入记录
            Document importRecord = document.get("importRecord", Document.class);
            importRecordService.deletByIds(Collections.singletonList(importRecord.getLong("id")));
            return true;
        }catch (Exception e){
            throw new ServiceException("删除流体数据失败");
        }
    }

    @Override
    public int save(MultipartFile file, IsfdFluidModelBo isfdModelBo) {
        String originalFileName = file.getOriginalFilename();
        String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length());
        OssClient storage = OssFactory.instance();
        UploadResult uploadResult;
        try {
            uploadResult = storage.uploadSuffix(file.getBytes(), suffix);
        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }
        // 保存文件信息
        saveModelDetail(originalFileName, suffix, storage.getConfigKey(), uploadResult, isfdModelBo);
        return 1;
    }

    @NotNull
    private void saveModelDetail(String originalfileName, String suffix, String configKey,
                                 UploadResult uploadResult, IsfdFluidModelBo isfdModelBo) {
        Map<String, Object> paramsMap  = new HashMap<>();
        paramsMap.put("desity", isfdModelBo.getDesity());
        paramsMap.put("name", isfdModelBo.getName());
        paramsMap.put("pressure", isfdModelBo.getPressure());
        paramsMap.put("temperature", isfdModelBo.getTemperature());
        paramsMap.put("specific_heat_capacity", isfdModelBo.getSpecificHeatCapacity());
        paramsMap.put("specific_heat_ratio", isfdModelBo.getSpecificHeatRatio());
        paramsMap.put("internal_energy", isfdModelBo.getInternalEnergy());
        paramsMap.put("gas_constant", isfdModelBo.getGasConstant());
        paramsMap.put("viscosity", isfdModelBo.getViscosity());
        paramsMap.put("thermal_conductivity", isfdModelBo.getThermalConductivity());
        paramsMap.put("mass_diffusivity",isfdModelBo.getMassDiffusivity());
        paramsMap.put("saturation_pressure", isfdModelBo.getSaturationPressure());
        paramsMap.put("saturation_temperature", isfdModelBo.getSaturationTemperature());
        paramsMap.put("latent_heat", isfdModelBo.getLatentHeat());
        paramsMap.put("surface_tension", isfdModelBo.getSurfaceTension());
        paramsMap.put("file_name", uploadResult.getFilename());
        paramsMap.put("original_name", originalfileName);
        paramsMap.put("file_suffix", suffix);
        paramsMap.put("service", configKey);
        //查询模型信息
        IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectModelByModelName("流体通用模型");
        // 记录record导入信息
        IsfdDatabaseDataImportRecordBo recordBo = new IsfdDatabaseDataImportRecordBo();
        IsfdBusinessDatabaseRefVo isfdBusinessDatabaseRefVo = isfdBusinessDatabaseRefMapper.selectDataBymodelId(modelConfig.getId());
        recordBo.setSceneId(isfdBusinessDatabaseRefVo.getSceneId());
        recordBo.setSystemId(isfdBusinessDatabaseRefVo.getSystemId());
        recordBo.setModelId(isfdBusinessDatabaseRefVo.getParentModelId());
        recordBo.setModelName(modelConfig.getModelName());
        recordBo.setTableName(modelConfig.getTableName());
        recordBo.setDatabaseTypeId(isfdBusinessDatabaseRefVo.getDatabaseTypeId());
        recordBo.setDataQuantity(1);

        String tableName = modelConfig.getTableName();
        Map<String, Integer> tableNameAndDataQuantity = new HashMap<>();
        tableNameAndDataQuantity.put(tableName, 1);
        IsfdDatabaseDataImportRecordBo dataImportRecordBo = importRecordService.createImportRecord(recordBo, IsfdImportMethodEnum.SITE, tableName, tableNameAndDataQuantity,  LoginHelper.getLoginUser());
        try {
            // 构建mongo数据
            Map<String, Object> mongoBo = new HashMap<>();
            mongoBo.put("importMethod", dataImportRecordBo.getImportMethod());
            mongoBo.put("id", dataImportRecordBo.getId());
            mongoBo.put("createBy", dataImportRecordBo.getCreateBy());
            mongoBo.put("updateBy", dataImportRecordBo.getUpdateBy());
            mongoBo.put("createTime", dataImportRecordBo.getCreateTime());
            mongoBo.put("updateTime", dataImportRecordBo.getUpdateTime());
            mongoBo.put("delete_flag", 0);
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> data = objectMapper.convertValue(paramsMap, new TypeReference<>() {
            });
            data.put("importRecord", mongoBo);
            // 保存数据
            String returnId = mongoService.save(modelConfig.getTableName(), data);
        } catch (Exception e) {
            // 删除导入记录
            isfdDatabaseDataManagementService.deleteDataByRecordId(dataImportRecordBo.getId());
            throw new ServiceException("流体数据保存失败");
        }
    }
    @Override
    public void download(String modelId, HttpServletResponse response) throws IOException {
        IsfdDatabaseModelConfig modelConfig = isfdDatabaseModelConfigMapper.selectModelByModelName("流体通用模型");
        Document document = mongoService.findById(modelConfig.getTableName(), modelId);
        if (ObjectUtil.isNull(document)) {
            throw new ServiceException("文件数据不存在!");
        }
        FileUtils.setAttachmentResponseHeader(response, document.getString("original_name"));
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
        OssClient storage = OssFactory.instance(document.getString("service"));
        long contentLength = storage.download(document.getString("file_name"), response.getOutputStream());
        response.setContentLengthLong(contentLength);
    }
    private IsfdFluidModelVo matchingUrl(IsfdFluidModelVo modelVo) {
        OssClient storage = OssFactory.instance(modelVo.getService());
        // 仅修改桶类型为 private 的URL，临时URL时长为120s
        if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
            modelVo.setUrl(storage.getPrivateUrl(modelVo.getFileName(), 120));
        }
        return modelVo;
    }
}
